package com.atguigu.consumer;

import com.atguigu.constant.MqConst;
import com.atguigu.constant.RedisConst;
import com.atguigu.entity.SeckillProduct;
import com.atguigu.entity.UserSeckillSkuInfo;
import com.atguigu.service.SeckillProductService;
import com.atguigu.util.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

@Component
public class SeckillConsumer {

    @Autowired
    private SeckillProductService seckillProductService;
    @Autowired
    private RedisTemplate redisTemplate;

    //1.接收秒杀商品上架的消息
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.SCAN_SECKILL_QUEUE, durable = "false"),
            exchange = @Exchange(value = MqConst.SCAN_SECKILL_EXCHANGE, durable = "false"),
            key = {MqConst.SCAN_SECKILL_ROUTE_KEY}))
    public void scanSeckillProductToRedis(){
        QueryWrapper<SeckillProduct> wrapper = new QueryWrapper<>();
        //1.秒杀状态为1的
        wrapper.eq("status",1);
        //2.取出当天的秒杀商品
        wrapper.eq("DATE_FORMAT(start_time,'%Y-%m-%d')", DateUtil.formatDate(new Date()));
        //3.判断秒杀商品的数量大于0
        wrapper.gt("num",0);
        List<SeckillProduct> seckillProductList = seckillProductService.list(wrapper);
        //4.把秒杀商品放入redis
        if (!CollectionUtils.isEmpty(seckillProductList)){
            for (SeckillProduct seckillProduct : seckillProductList) {
                String skuId = seckillProduct.getSkuId().toString();
                //商品以hash结构存储
                redisTemplate.boundHashOps(RedisConst.SECKILL_PRODUCT).put(skuId,seckillProduct);
                //把秒杀商品数量存储到list里面
                for (int i = 0; i < seckillProduct.getNum(); i++) {
                    redisTemplate.boundListOps(RedisConst.SECKILL_STOCK_PREFIX+skuId).leftPush(skuId);
                }
                //通知其他节点修改秒杀状态位
                redisTemplate.convertAndSend(RedisConst.PREPARE_PUB_SUB_SECKILL,skuId+":"+RedisConst.CAN_SECKILL);
            }
        }
    }
    //2.接收秒杀商品预下单的消息
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.PREPARE_SECKILL_QUEUE, durable = "false"),
            exchange = @Exchange(value = MqConst.PREPARE_SECKILL_EXCHANGE, durable = "false"),
            key = {MqConst.PREPARE_SECKILL_ROUTE_KEY}))
    public void prepareSeckill(UserSeckillSkuInfo userSeckillSkuInfo){
        if (userSeckillSkuInfo!=null){
            //处理预下单
            seckillProductService.prepareSeckill(userSeckillSkuInfo);
        }
    }

    //3.秒杀商品下架的操作
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.CLEAR_REDIS_QUEUE, durable = "false"),
            exchange = @Exchange(value = MqConst.CLEAR_REDIS_EXCHANGE, durable = "false"),
            key = {MqConst.CLEAR_REDIS_ROUTE_KEY}))
    public void clearSeckill(UserSeckillSkuInfo userSeckillSkuInfo){
        QueryWrapper<SeckillProduct> wrapper = new QueryWrapper<>();
        //1.秒杀状态为1的
        wrapper.eq("status",1);
        //2.把结束时间小于等于当前的商品下架
        wrapper.le("end_time", new Date());
        List<SeckillProduct> seckillProductList = seckillProductService.list(wrapper);
        if (!CollectionUtils.isEmpty(seckillProductList)){
            for (SeckillProduct seckillProduct : seckillProductList) {
                //修改状态为以下架
                seckillProduct.setStatus("2");
                seckillProductService.updateById(seckillProduct);
                //删除redis中秒杀商品信息
                redisTemplate.delete(RedisConst.SECKILL_STOCK_PREFIX+seckillProduct.getSkuId());
                redisTemplate.delete(RedisConst.SECKILL_STATE_PREFIX+seckillProduct.getSkuId());
                redisTemplate.delete(RedisConst.PREPARE_SECKILL_USERID_SKUID+":*");
            }
            redisTemplate.delete(RedisConst.SECKILL_PRODUCT);
            //删除前在数据库存储一份订单信息
            redisTemplate.delete(RedisConst.PREPARE_SECKILL_USERID_ORDER);
            redisTemplate.delete(RedisConst.BOUGHT_SECKILL_USER_ORDER);
        }
    }
}
